<?php
/**
 * Copyright (c) 2012, Jiehun.com.cn Inc. All Rights Reserved
 * @author Ronnie(dengxiaolong@jiehun.com.cn)
 * @date 2012-2-11
 * @version 1.0
 * @brief
 *
 **/
final class Image
{
	const ORIGIN = 'origin';
	const CROP = 'crop';
	const THUMB = 'thumb';
	const FILL = 'fill';
	
	// gif
	const IMAGETYPE_GIF = 0;
	// jpeg
	const IMAGETYPE_JPEG = 1;
	// png
	const IMAGETYPE_PNG = 2;
	// swf
	const IMAGETYPE_SWF = 3;

	//aac
	const MEDIATYPE_AAC = 1;
	
	const MAX_WIDTH = 2000;

	private $savedir;
	private $tmpdir;
	private $localdir;
	private $imagehandler = 'Imagick';
	private $quality;
	private $rules;
	private $watermark;
	private $hosts;
	private $hostNum;

	private static $handlerCache = array();

	/**
	 *
	 * @param array $options
	 * @param string $saveDir 必选 图片保存路径
	 * @param string $imagehandler: 可选 图片处理器 默认为imagick
	 * </code>
	 */
	public function __construct($conf)
	{
		if (!isset($conf['savedir'])) {
			throw new Exception('image.savedirNotDefined');
		}
		$this->savedir = $conf['savedir'];
		$this->localdir = $conf['localdir'];
		$this->quality = isset($conf['quality']) ? intval($conf['quality']) : 99;
		
		$this->rules = isset($conf['rules']) ? $conf['rules'] : array();
		
		$this->tmpdir = isset($conf['tmpdir']) ? $conf['tmpdir'] : $this->savedir;
		
		$this->watermark = isset($conf['watermark']) ? $conf['watermark'] : false;
		
		$this->hosts = isset($conf['host']) ? $conf['host'] : array('');
		if (is_string($this->hosts)) {
			$this->hosts = array($this->hosts);
		}
		$this->hostNum = count($this->hosts);
	}
	/**
	 * 获取一个随机路径
	 */
	private function getTmpPath()
	{
		return $this->tmpdir.'/'.microtime(true).rand(1000,9999);
	}
	
/**
	 * 获取本地一个随机路径
	 */
	private function getRomdomPath($dir,$rodom)
	{
		return $dir .'/'.$rodom;
	}
	

	/**
	 * 保存图片
	 * @param string $path
	 * @return int 64位有符号整数
	 */
	public function save($path)
	{
		list($w, $h, $t) = getimagesize($path);
		// 如果是flash，直接返回地址
		if ($t == 4 || $t == 13) {
			return $this->getIdByPath($path);
		} 

		$quality = $this->quality;
		$ih = $this->getImageHandler();
		$tmpPath = $this->getTmpPath();
		copy($path, $tmpPath);
		
		if ($t > 4) {
			$ih->changeFormat($tmpPath, $tmpPath, 'png');
		}
		
		// 将图片缩放到一定大小
		$ih->thumb($tmpPath, $tmpPath, self::MAX_WIDTH, null);
		
		if ($quality > 0 && $quality < 100) {
			$ih->compress($tmpPath, $tmpPath, $quality);
		}
		
		$imageId = $this->getIdByPath($tmpPath);
		unlink($tmpPath);
		return $imageId;
	}

	
	/**
	 * 保存图片原图到本地和图片服务器
	 * @param string $path
	 * @return int 64位有符号整数
	 */
	public function saveLocalAndServer($path)
	{
		
		list($w, $h, $t) = getimagesize($path);
		
		// 如果是flash，直接返回地址
		if ($t == 4 || $t == 13) {
			return $this->getIdByPath($path);
		} 
        
		$quality = $this->quality;
		$ih = $this->getImageHandler();
		
		$romdem = microtime(true).rand(1000,9999);
		
		$tmpPath = $this->getRomdomPath($this->tmpdir,$romdem);
		
		$lcoalPath = $this->getRomdomPath($this->localdir,$romdem);
		
	//	$tmpPath = $this->getTmpPath();
		copy($path, $tmpPath);
	
		copy($path, $lcoalPath);
		
		if ($t > 4) {
			$ih->changeFormat($lcoalPath, $tmpPath, 'png');  //从本地拷贝到图片服务器
		    $ih->changeFormat($lcoalPath, $lcoalPath, 'png');
		}
		
		// 将图片缩放到一定大小
		$ih->thumb($lcoalPath, $tmpPath, self::MAX_WIDTH, null);
		$ih->thumb($lcoalPath, $lcoalPath, self::MAX_WIDTH, null);
		if ($quality > 0 && $quality < 100) {
			$ih->compress($lcoalPath, $tmpPath, $quality); //从本地拷贝到图片服务器
			$ih->compress($lcoalPath, $lcoalPath, $quality);
		}
	
		$imageId = $this->getIdByPathLocal($tmpPath);
		
		unlink($tmpPath);
		return $imageId;
		
	}
	
	/**
	*存储多媒体文件
	*$path 临时文件地址
	*$type 文件类型 1 音频 2 视频
	*/
	public function saveMediaFile($path,$type=self::MEDIATYPE_AAC)
	{
		// 获取文件id
		$sign62 = self::createSign62($path);
		$fileId = $sign62 << 3 | $type;

		$to = $this->getMediaFilePath($fileId,$type);
		if (file_exists($to)) {
			return $fileId;
		}
		$dir = dirname($to);
		if (!is_dir($dir)) {
			mkdir(dirname($to), 0777, true);
		}
		copy($path, $to);
		unlink($path);
		return $fileId;
	}
	
	/**
	 * 对原始图做一个水印，并返回地址
	 * @param long $imageId
	 * @return string | false
	 */
	public function watermarkOrigin($imageId)
	{
		if (!$this->watermark) {
			return false;
		}
		$path = $this->getFilePath($imageId, 'origin', 0, 0);
		$newPath = $this->getFilePath($imageId, 'origin', 0, 0, true);
		if (!is_file($newPath)) {
			$dir = dirname($newPath);
			if (!is_dir($dir)) {
				mkdir($dir, 0777, true);
			}
			copy($path, $newPath);
			$this->_resize($path, $newPath, 0, 0, 'origin', true);
		}
		return $this->getUrl($imageId, 0, 0, 'origin', true);
	}
	
	/**
	 * 对原始图做一个水印，并返回地址 litiezhu 增加读取本地原图
	 * @param long $imageId
	 * @return string | false
	 */
	public function watermarkOriginLocal($imageId,$waterMarkPath)
	{
		if (!$this->watermark) {
			return false;
		}
	
		$path = $this->getLocalFilePath($imageId, 'origin', 0, 0);
		$newPath = $this->getFilePath($imageId, 'origin', 0, 0, true);
		
		if (!is_file($newPath)) {
			$dir = dirname($newPath);
			if (!is_dir($dir)) {
				mkdir($dir, 0777, true);
			}
			copy($path, $newPath);
			$this->_resizeByLocal($path, $newPath, 0, 0, 'origin', true,$waterMarkPath);
		}
		return $this->getUrl($imageId, 0, 0, 'origin', true);
	}
	
	/**
	 * 是否为有效的规则
	 * @param int $width
	 * @param int $height
	 * @param int $type
	 */
	public function getRuleName($width, $height, $type)
	{
		foreach($this->rules as $ruleName => $rule) {
			if (!isset($rule['type'])) {
				$rule['type'] = 'thumb';
			}
			if ($width == $rule['width'] && $height == $rule['height'] && $type == $rule['type']) {
				return $ruleName;
			}
		}
		return false;
	}
	
	/**
	 * 将图片进行裁剪后保存
	 * @param string $path
	 * @param array $option
	 * <code>array(
	 * 	left: int 默认为0
	 *  top: int 默认为0
	 *  width: int
	 *  height: int
	 *  rate: float 缩放比率
	 * )<code>
	 */
	public function cropSave($path, array $option)
	{
		$left = isset($option['left']) ? intval($option['left']) : 0;
		$top = isset($option['top']) ? intval($option['top']) : 0;
		$width = isset($option['width']) ? intval($option['width']) : 0;
		$height = isset($option['height']) ? intval($option['height']) : 0;

		if ($width <= 0 || $height <= 0) {
			throw new Exception('image.sizeWrong width='.$width.' height='.$height);
		}
		$rate = isset($option['rate']) ? $option['rate'] : 1;
		if (!is_numeric($rate) || $rate <= 0) {
			throw new Exception('image.rateWrong rate='.$rate);
		}

		$ih = $this->getImageHandler();
		if ($rate != 1) {
			$ih->zoom($path, $path, $rate);
		}

		$ih->crop($path, $path, $left, $top, $width, $height);
		return $this->getIdByPath($path);
	}
	
	/**
	 * 通过规格名称来压缩图片
	 * 
	 * @param int $imageId
	 * @param string $ruleName
	 * @param boolean | NULL $watermark 
	 * @param boolean $detail 是否返回详细信息
	 */
	public function resizeByRuleName($imageId, $ruleName, $watermark = NULL, $detail = FALSE)
	{
		list($width, $height, $type, $wm) = $this->getDefaultOption($ruleName);
		if ($watermark !== NULL) {
			$wm = $watermark;
		}
		return $this->resize($imageId, $width, $height, $type, $wm, $detail);
	}

	/**
	 * 调整图片大小
	 *
	 * @param int $imageId 
	 * @param int $width  必须为大于0的正数
	 * @param int $height  必须为大于0的正数
	 * @param string $type  类型：thumb 缩略图 crop 裁剪 fill 缩略并填充背景色
	 * @param boolean $watermark 是否包含水印
	 * @param boolean $detail 是否返回详细信息
	 * @throws Exception image.u_wrongsize 图片尺寸不正确
	 * @return string 图片的地址
	 */
	public function resize($imageId, $width, $height, $type = self::THUMB, $watermark = FALSE, $detail = FALSE) {
		$this->_checkRule($width, $height, $type);
		
		$from = $this->getFilePath($imageId);
		if (!is_file($from)) {
			throw new Exception('image.fileNotExists imageId='.$imageId);
		}

		$to = $this->getFilePath($imageId, $type, $width, $height, $watermark);
		if (!is_file($to)) {
			$dir = dirname($to);
			if (!is_dir($dir)) {
				mkdir(dirname($to), 0777, true);
			}
			
			$this->_resize($from, $to, $width, $height, $type, $watermark);
		}
		
		return $this->getUrl($imageId, $width, $height, $type, $watermark, $detail);
	}
	
	/**
	 * 通过本地获取原图规格名称来压缩图片
	 * 
	 * @param int $imageId
	 * @param string $ruleName
	 * @param boolean | NULL $watermark 
	 * @param boolean $detail 是否返回详细信息
	 */
	public function resizeByRuleNameLocal($imageId, $ruleName, $watermark = NULL, $detail = FALSE,$waterMarkPath)
	{
		list($width, $height, $type, $wm) = $this->getDefaultOption($ruleName);
		if ($watermark !== NULL) {
			$wm = $watermark;
		}
		return $this->resizeLocal($imageId, $width, $height, $type, $wm, $detail,$waterMarkPath);
	}
	
	/**
	 * 从本地获取原图信息调整图片大小
	 *
	 * @param int $imageId 
	 * @param int $width  必须为大于0的正数
	 * @param int $height  必须为大于0的正数
	 * @param string $type  类型：thumb 缩略图 crop 裁剪 fill 缩略并填充背景色
	 * @param boolean $watermark 是否包含水印
	 * @param boolean $detail 是否返回详细信息
	 * @throws Exception image.u_wrongsize 图片尺寸不正确
	 * @return string 图片的地址
	 */
	public function resizeLocal($imageId, $width, $height, $type = self::THUMB, $watermark = FALSE, $detail = FALSE,$waterMarkPath) {
		$this->_checkRule($width, $height, $type);
		
		$from = $this->getLocalFilePath($imageId);
		if (!is_file($from)) {
			throw new Exception('image.fileNotExists imageId='.$imageId);
		}

		$to = $this->getFilePath($imageId, $type, $width, $height, $watermark);
		if (!is_file($to)) {
			$dir = dirname($to);
			if (!is_dir($dir)) {
				mkdir(dirname($to), 0777, true);
			}
			
			$this->_resizeByLocal($from, $to, $width, $height, $type, $watermark,$waterMarkPath);
		}
		
		return $this->getUrl($imageId, $width, $height, $type, $watermark, $detail);
	}
	/**
	 * 检查图片规格是否符合规范
	 * @param int $width
	 * @param int $height
	 * @param string $type
	 */
	private function _checkRule($width, $height, $type)
	{
		switch($type) {
			case self::THUMB:
				if (!( ( ($width === null && $height > 0) || ($height === null && $width > 0) || ($width > 0 && $height > 0)) )) {
					throw new Exception('image.u_wrongSize width:'.$width.' height='.$height);
				}
				break;
			case self::FILL:
			case self::CROP:
				if ($width <= 0 || $height <= 0) {
					throw new Exception('image.u_wrongSize width:'.$width.' height='.$height);
				}
				break;
		}
	}
	
	/**
	 * 实际调整图片的大小
	 * @param string $from
	 * @param string $to
	 * @param int $width
	 * @param int $height
	 * @param string $type
	 * @param boolean $watermark
	 */
	private function _resize($from, $to, $width, $height, $type, $watermark) 
	{
		$ih = $this->getImageHandler();
		switch($type) {
			case self::CROP:
				$ih->cropThumb($from, $to, $width, $height);
				break;
			case self::THUMB:
				$ih->thumb($from, $to, $width, $height);
				break;
			case self::FILL:
				$ih->fillThumb($from, $to, $width, $height);
				break;
		}
	    $this->doBackGroudWaterMark($from, $to, $width, $height, $type, $watermark);
		// 设置水印
		
	}
	/**
	 * 在水印图片上打背景水印,按照
	 */
	private function doBackGroudWaterMark($from, $to, $width, $height, $type, $watermark) 
	{
		
		    $ih = $this->getImageHandler();
		    $aleft = array();
			$atop = array();
			$awatermark =  array();
			if ($watermark && $this->watermark) {
					if ($this->needWatermark($to)) {
						list($width, $height) = getimagesize($to);
						list($wWidth, $wHeight) = getimagesize($this->watermark['path']);
						$left = false;
						$top = false;
						if (isset($this->watermark['left'])) {
							$left = $this->watermark['left'];
						} else if (isset($this->watermark['right'])) {
							$left = $width - $this->watermark['right'] - $wWidth;
						} else {
							$left = 0;
						}
						
						if (isset($this->watermark['top'])) {
							$top = $this->watermark['top'];
						} else if (isset($this->watermark['bottom'])) {
							$top = $height - $this->watermark['bottom'] - $wHeight;
						} else {
							$top = 0;
						}
						
						if ($left === false || $top === false) {
							throw new Exception('image.u_positionNotSet');
						}
						if(!empty($waterMarkPath)){
							 $awatermark[0] = $waterMarkPath;
						}else{
							$awatermark[0] = $this->watermark['path'];
						}
				
						$aleft[0] = $left;
					    $atop[0] = $top;
					   
						if(isset($this->watermark['backgroud_path'])){
								list($width, $height) = getimagesize($to);
								list($wWidth, $wHeight) = getimagesize($this->watermark['path']);
								list($bWidth, $bHeight) = getimagesize($this->watermark['backgroud_path']);
								
								//计算可以打几倍高度
							    $h_times = ($height - $wHeight-10)/(3*$bHeight)-1;
							    $w_times = $width/$bWidth;
							    if($h_times>3){
							    	$h_times = 3;  //最多3行
							    }
							    $k=1;
							    for($i=0;$i<$h_times && $i<=2;$i++){ //高度循环
							     	for($j=0;$j<$w_times && $j<=1;$j++){   //宽度循环，最多两次
							     	 	$temp_w1 = $j*($width/2);
							     	 	$temp_w2 = $width/2*($j+1)-$bWidth;
							     	 	if($temp_w1>$temp_w2){
							     	 		$temp_w1 =  $temp_w2;
							     	 	}
							     	 	if($h_times>1){
							     	 		$temp_h1 = ($height-$wHeight-10)/($h_times+1)*$i;
							     	 		$temp_h2 = ($height-$wHeight-10)/($h_times+1)*($i+1)-2*$bHeight;
							     	 	}else{
							     	 		$temp_h1 = ($height-$wHeight-10)/$h_times*$i;
							     	 		$temp_h2 = ($height-$wHeight-10)/$h_times-2*$bHeight;
							     	 	}
							     	 	if($temp_h1>$temp_h2){
							     	 		$temp_h1 =  $temp_h2;
							     	 	}
							     		$aleft[$k] = mt_rand($temp_w1,$temp_w2);
							     		$atop[$k] = mt_rand($temp_h1,$temp_h2);
							     		$awatermark[$k] = $this->watermark['backgroud_path'];
		
							     		$k++;
							     	}
							    }
							   
								
							}
							$ih->mergeByArray($to, $awatermark, $to, $aleft, $atop);
						}
		// 设置水印
		    
				
		   }
			
	}
		/**
	 * 实际调整图片的大小，按照城市区号打水印
	 * @param string $from
	 * @param string $to
	 * @param int $width
	 * @param int $height
	 * @param string $type
	 * @param boolean $watermark
	 */
	private function _resizeByLocal($from, $to, $width, $height, $type, $watermark,$waterMarkPath) 
	{
		$ih = $this->getImageHandler();
		switch($type) {
			case self::CROP:
				$ih->cropThumb($from, $to, $width, $height);
				break;
			case self::THUMB:
				$ih->thumb($from, $to, $width, $height);
				break;
			case self::FILL:
				$ih->fillThumb($from, $to, $width, $height);
				break;
		}

		// 设置水印
		
				$this->doBackGroudWaterMark($from, $to, $width, $height, $type, $watermark);
				
			
	}
	
	/**
	 * 是否需要打水印
	 * @param string $path
	 */
	public function needWatermark($path)
	{
		list($width, $height, $format) = getimagesize($path);
		// GIF图片不进行打水印的操作
		if ($format == 1) {
			return false;
		}
		$minWidth = isset($this->watermark['minWidth']) ? $this->watermark['minWidth'] : 0;
		$minHeight = isset($this->watermark['minHeight']) ? $this->watermark['minHeight'] : 0;
		if ( (!$minWidth || $minWidth <= $width) && (!$minHeight || $minHeight <= $height)) {
			return true;
		}
		return false;
	}
	
	/**
	 * 根据规则名称返回图片路径
	 * 
	 * @param int $imageId
	 * @param string $ruleName
	 * @param boolean | NULL $watermark
	 * @param string $tmpHost
	 * @return string
	 */
	public function getUrlByRuleName($imageId, $ruleName, $watermark = NULL, $tmpHost = '')
	{
		list($width, $height, $type, $wm) = $this->getDefaultOption($ruleName);
		if ($watermark !== NULL) {
			$wm = $watermark;
		}
		return $this->getUrl($imageId, $width, $height, $type, $wm, $tmpHost);
	}
	
	/**
	 * 对URL进行解析
	 * @param string $url
	 * @return array | false
	 * <code>
	 * array(
	 * 	id        图片id
	 *  type      图片类型，可以是 crop、thumb、fill、origin
	 *  watermark 是否打过水印
	 *  width     宽度。如果没有指定，则为null
	 *  height    高度。如果没有指定，则为null
	 *  ext       后缀。可以为jpg、png、swf、gif等
	 *  url       被匹配的url部分
	 * )
	 * </code>
	 */
	public function parseUrl($url)
	{
		$info = @parse_url($url);
		if (!$info || empty($info['path'])) return false;
		if (preg_match("/(crop|thumb|fill|origin)\/\d{3}\/\d{3}\/(\d+)([0-3])(?:\-(\d+)?[xX](\d+)?)?.(jpg|gif|png|swf)/", $info['path'], $matches)) {
			$ret = array();
			$ret['type'] = $matches[1];
			$id = $matches[2];
			$tag = $matches[3] & 1;
			$watermark = ($matches[3] & 2) > 0;
			if ($tag > 0) {
				$id = intval($id);
			} else {
				$id = intval('-'.$id);
			}
			$ret['id'] = $id;
			$ret['watermark'] = $watermark;
			$ret['width'] = $matches[4] ? intval($matches[4]) : null;
			$ret['height'] = $matches[5] ? intval($matches[5]) : null;
			$ret['ext'] = $matches[6];
			
			if (isset($info['host'])) {
				if (isset($info['port']) && $info['port'] != 80) {
					$ret['host'] = $info['host'].':'.$info['port'];
				} else {
					$ret['host'] = $info['host'];
				}
			} else {
				$ret['host'] = '';
			}
			$ret['path'] = $info['path'];
			$ret['protocol'] = isset($info['scheme']) ? $info['scheme'] : 'http';
			return $ret;
		}
		return false;
	}
	
	/**
	 * 得到默认配置参数
	 * @param string $ruleName
	 * @return array
	 */
	private function getDefaultOption($ruleName)
	{
		if (preg_match("{(\d+)[xX](\d+)}", $ruleName, $matches)) {
			$option = array(
				'width'  => $matches[1],
				'height' => $matches[2],
				'type'	 => self::FILL,
				'watermark' => false,
			);	
		} else {
			if (!isset($this->rules[$ruleName])) {
				throw new Exception('image.ruleNotFind rulename='.$ruleName);
			}
			$option = $this->rules[$ruleName];
		}
		
		$width = isset($option['width']) ? intval($option['width']) : $option['width'];
		$height = isset($option['height']) ? intval($option['height']) : $option['height'];
		$type = isset($option['type']) ? $option['type'] : self::THUMB;
		$watermark = isset($option['watermark']) ? $option['watermark'] : false;
		
		return array($width, $height, $type, $watermark);
	}

	/**
	 * 根据图片id及裁剪选项获取图片路径
	 *
	 * @param int $imageId
	 * @param int $width
	 * @param int $height
	 * @param string $type
	 * @param boolean $watermark
	 * @param boolean $detail 是否返回详细信息
	 * @param string $tmpHost 临时主机
	 */
	public function getUrl($imageId, $width, $height, $type = self::THUMB, $watermark = FALSE, $detail = FALSE, $tmpHost = '')
	{
		$path = self::getImagePath($imageId, $type, $width, $height, $watermark);
		
		$host = $tmpHost ? $tmpHost : $this->getImageHost($imageId);
		if (!$detail) {
			return 'http://'.$host.'/'.$path;
		}
		
		$realpath = $this->savedir.'/'.$path;
		$ret = array(
			'id'    => $imageId,
			'path'  => $realpath,
			'url'	=> 'http://'.$host.'/'.$path,
			'watermark' => $watermark,
		);
		
		if (!is_readable($realpath)) {
			$ret['exists'] = false;
		} else {
			$ret['exists'] = true;
			
			$info = @getimagesize($realpath);
			$ret['mime'] = $info ? $info['mime'] : false;
			$ret['width'] = $info ? $info[0] : false;
			$ret['height'] = $info ? $info[1] : false;
		}
		return $ret;
	}

	/**
	 * 获取原始图片地址
	 * 
	 * @param int $imageId
	 * @param boolean $watermark 
	 * @param boolean $detail
	 * @param string $tmpHost
	 */
	public function getOriginUrl($imageId, $watermark = false, $detail = FALSE, $tmpHost = '')
	{
		return $this->getUrl($imageId, 0, 0, 'origin', $watermark, $detail, $tmpHost);
	}

	
	/**
	 * 根据图片id及裁剪选项获取图片路径
	 *
	 * @param int $imageId
	 * @param int $width
	 * @param int $height
	 * @param string $type
	 * @param boolean $watermark
	 * @param boolean $detail 是否返回详细信息
	 * @param string $tmpHost 临时主机
	 */
	public function getLocalUrl($imageId, $width, $height, $type = self::THUMB, $watermark = FALSE, $detail = FALSE, $tmpHost = '')
	{
		$path = self::getImagePath($imageId, $type, $width, $height, $watermark);
		$host = $tmpHost ? $tmpHost : $this->getImageHost($imageId);
		if (!$detail) {
			return 'http://'.$host.'/'.$path;
		}
		
		$realpath = $this->localdir.'/'.$path;
		$ret = array(
			'id'    => $imageId,
			'path'  => $realpath,
			'url'	=> 'http://'.$host.'/'.$path,
			'watermark' => $watermark,
		);
		
		if (!is_readable($realpath)) {
			$ret['exists'] = false;
		} else {
			$ret['exists'] = true;
			
			$info = @getimagesize($realpath);
			$ret['mime'] = $info ? $info['mime'] : false;
			$ret['width'] = $info ? $info[0] : false;
			$ret['height'] = $info ? $info[1] : false;
		}
		return $ret;
	}

	/**
	 * 获取原始图片地址
	 * 
	 * @param int $imageId
	 * @param boolean $watermark 
	 * @param boolean $detail
	 * @param string $tmpHost
	 */
	public function getLocalOriginUrl($imageId, $watermark = false, $detail = FALSE, $tmpHost = '')
	{
		return $this->getLocalUrl($imageId, 0, 0, 'origin', $watermark, $detail, $tmpHost);
	}
	
	/**
	*获取媒体文件图片地址
	 * 
	 * @param int $fileId
	 * @param string $tmpHost
	*/
	public function getMediaUrl($fileId,$tmpHost='')
	{
		$path = self::getMediaPath($fileId,$fileId&7);
		return ($tmpHost?$tmpHost:$this->hosts[0]).'/'.$path;
	}
	
	/**
	 * 通过文件路径获取图片id
	 *
	 * @param string $path
	 * @return int
	 */
	private function getIdByPath($path)
	{
		// 获取文件id
		$imageId = $this->getImageId($path);
		$to = $this->getFilePath($imageId);
		if (file_exists($to)) {
			return $imageId;
		}
		$dir = dirname($to);
		if (!is_dir($dir)) {
			mkdir(dirname($to), 0777, true);
		}
		copy($path, $to);
		return $imageId;
	}
	/**
	 * 
	 * Enter description here ...
	 * @param unknown_type $serverFile
	 * @param unknown_type $localFile
	 */
	private function copyToLocal($serverFile,$localFile){
		
		if (!file_exists($localFile)) {
			$dir = dirname($localFile);
			if (!is_dir($dir)) {
				mkdir(dirname($localFile), 0777, true);
			}
			copy($serverFile, $localFile);
		}
		
	
	}

		/**
	 * 通过文件路径获取图片id
	 *
	 * @param string $path
	 * @return int
	 */
	private function getIdByPathLocal($path)
	{
		// 获取文件id
		$imageId = $this->getImageId($path);
		$to = $this->getFilePath($imageId);
		$toLocal =  $this->getLocalFilePath($imageId);
		if (!file_exists($to)) {
			$dir = dirname($to);
			if (!is_dir($dir)) {
				mkdir(dirname($to), 0777, true);
			}
		}
		
	    if (file_exists($toLocal)) {
			return $imageId;
		}
		$dir = dirname($toLocal);
		if (!is_dir($dir)) {
			mkdir(dirname($toLocal), 0777, true);
		}
		copy($path, $to);
		copy($path, $toLocal);
		return $imageId;
	}
	

	/**
	 * 根据文件ID获取路径
	 *
	 * @param long $imageId
	 * @param int $type
	 * @param int $width
	 * @param int $height
	 * @return string
	 */
	function getFilePath($imageId, $type = self::ORIGIN, $width = 0, $height = 0, $watermark = FALSE)
	{
		return $this->savedir.'/'.$this->getImagePath($imageId, $type, $width, $height, $watermark);
	}
	
	/**
	 * 根据文件ID获取本地路径
	 *
	 * @param long $imageId
	 * @param int $type
	 * @param int $width
	 * @param int $height
	 * @return string
	 */
	function getLocalFilePath($imageId, $type = self::ORIGIN, $width = 0, $height = 0, $watermark = FALSE)
	{
		return $this->localdir.'/'.$this->getImagePath($imageId, $type, $width, $height, $watermark);
	}
	


	/**
	 * 根据文件ID获取路径
	 *
	 * @param long $imageId
	 * @param int $type
	 * @param int $width
	 * @param int $height
	 * @param boolean $waterMark 是否包含水印
	 * @return string
	 */
	private function getImagePath($imageId, $type = self::ORIGIN, $width = 0, $height = 0, $watermark = FALSE)
	{
		$offset = 3;
		$start = 0;
		$imageType = $imageId & 3;
		$ext = '';
		switch($imageType) {
			case self::IMAGETYPE_SWF:
				$ext = 'swf';
				break;
			case self::IMAGETYPE_GIF:
				$ext = 'gif';
				break;
			case self::IMAGETYPE_JPEG:
				$ext = 'jpg';
				break;
			case self::IMAGETYPE_PNG:
				$ext = 'png';
				break;
		}

		$tag = $imageId > 0 ? 1 : 0;
		if ($watermark) {
			$tag = $tag | 2;
		}
		$tag = ''.$tag;
		$fileName = abs($imageId).$tag;
		$fileName = sprintf('%06s', $fileName);
		$path = implode('/', array(
		$type,
		substr($fileName, $start, $offset),
		substr($fileName, $start + $offset, $offset),
		$fileName,
		));
		if ($type != self::ORIGIN && ($width > 0 || $height > 0)) {
			$path .= '-'.$width. 'X'.$height;
		}
		$path .= '.'. $ext;

		return $path;
	}

	/**
	*获取媒体文件路径
	*/
	private function getMediaPath($fileId,$fileType=self::MEDIATYPE_AAC)
	{
		$offset = 3;
		$start = 0;
		$fileType = $fileId & 7;
		$ext = '';
		switch($fileType) {
			case self::MEDIATYPE_AAC:
				$ext = 'aac';
				break;
		}

		$tag = $fileId > 0 ? 1 : 0;
		$fileName = abs($fileId);
		$fileName = sprintf('%06s', $fileName);
		$path = implode('/', array(
					$fileType,
					substr($fileName, $start, $offset),
					substr($fileName, $start + $offset, $offset),
					$fileName,
					));
		$path .= '.'. $ext;
		return 'audio/'.$path;
	}

	/**
	*获取媒体文件路径
	*/
	private function getMediaFilePath($fileId,$fileType=self::MEDIATYPE_AAC)
	{
		return $this->savedir.'/'.$this->getMediaPath($fileId,$fileType);
	}

	
	/**
	 * 获取图片的主机名
	 * @param int | string $imageId
	 */
	public function getImageHost($imageId)
	{
		if (!is_numeric($imageId)) {
			$filename =  pathinfo($imageId, PATHINFO_FILENAME);
			$imageId = chr(substr($filename, -1));
		} else {
			$imageId = $imageId >> 2;
		}
		switch($this->hostNum) {
			case 1:
				return $this->hosts[0];
			case 2:
			case 4:
			case 8:
			case 16:
				$key = $imageId & ($this->hostNum - 1);
				return $this->hosts[$key];
			default:
				$key = $imageId % $this->hostNum;
				return $this->hosts[$key];
		}
	}
	
	/**
	 * 获取图片处理器
	 * @return ImageHandlerInterface
	 */
	private function getImageHandler()
	{
		$handlerName = $this->imagehandler;
		$className = $handlerName.'Impl';
		if (isset(self::$handlerCache[$handlerName])) {
			return new $className();
		}

		$file = dirname(__FILE__).'/handler/'.$handlerName.'Impl.php';
		if (!is_file($file)) {
			throw new Exception('image.handlerNotExist handler='.$handlerName);
		}
		self::$handlerCache[$handlerName] = true;
		require_once $file;
		return new $className();
	}

	/**
	 * get the imageId by the path
	 * @param string $path
	 * @return int 64位有符号整数  1、2位表示图片类型 3-64位表示图片的映射id
	 */
	public function getImageId($path)
	{
		list($w, $h, $type) = getimagesize($path);
		switch($type) {
			case 4: // IMAGETYPE_SWF
			case 13:
				$type = self::IMAGETYPE_SWF;
				break;
			case 1: // IMAGETYPE_GIF
				$type = self::IMAGETYPE_GIF;
				break;
			case 2: // IMAGETYPE_JPEG
				$type = self::IMAGETYPE_JPEG;
				break;
			case 3: // IMAGETYPE_PNG
				$type = self::IMAGETYPE_PNG;
				break;
			default:
				throw new Exception('image.wrongImageFormat type='.$type);
		}
		$sign62 = self::createSign62($path);
		return $sign62 << 2 | $type;
	}

	/**
	 * 根据文件创建对应的62位标识
	 *
	 * @param string $path
	 * @return int  62 byte
	 */
	private function createSign62($path)
	{
		if (!is_file($path)) {
			return 0;
		}
		$hash = md5_file ( $path, true );
		$high = substr ( $hash, 0, 8 );
		$low = substr ( $hash, 8, 8 );
		$sign = $high ^ $low;
		$sign1 = hexdec ( bin2hex ( substr ( $sign, 0, 4 ) ) );
		$sign2 = hexdec ( bin2hex ( substr ( $sign, 4, 4 ) ) );
		return $sign1 << 30 | $sign2;
	}
		/**
        * 根据图片规格和水印 和图片id删除一个图片
        */
       function delImg($imageId,$rules,$watermark=0){
               if(empty($imageId) || empty($rules)){
                       throw new Exception ('image.deleteImgEmptyImgIdorRule');
               }
               $watermark = empty($watermark)?false:true;
               foreach($rules as $k=>$rule){
                       Logger::trace("ruleIs:".$rule);
                       list($width, $height, $type, $wm) = $this->getDefaultOption($rule);
                       if($rule=='origin'){
                               if(!empty($watermark)){
                                       $pathes[] = $this->getFilePath($imageId, $rule, 0, 0, $watermark);
                               }
                               $pathes[] = $this->getFilePath($imageId, $rule);
                      	}else if($rule=='editor'){
                               $pathes[] = $this->getFilePath($imageId, $type, $width, $height, $watermark);
                       }else{
                               $pathes[] = $this->getFilePath($imageId, $type, $width, $height);
                       }
              }
               //var_dump($pathes);
              foreach($pathes as $k=>$path){
                       if(file_exists($path)){
                               if(@unlink($path)==false){
                                       return false;
                               }else{
                                       Logger::trace("unlinkSucces:".$path);
                               }
                       }else{
                               Logger::trace("fileNotExists:".$path);
                       }
               }
               return true;
      }
}
